<?php

namespace models;

use system\Model;

class SysTokens extends Model {
    // token类
    protected $auto = [
        ['create_time', 'time', self::MODEL_INSERT, 'function']
    ];

    /**
     * 生成一个token
     *
     * @param int $uid
     * @param int $type 1后台用户 2普通用户
     *
     * @return bool|string
     */
    protected function generateToken($uid, $type = 1) {
        $token = sha1(md5($_SERVER['HTTP_USER_AGENT'] . uniqid() . $uid));
        $map   = [
            'token' => $token,
            'type'  => $type,
        ];
        if ($this->getFind($map, 'id')) {
            return false;
        }

        return $token;
    }

    /**
     * 获取用户所有有效token
     *
     * @param string $uid
     * @param int    $type 1后台用户 2普通用户
     *
     * @return array
     */
    public function getUidTokens($uid = '', $type = 1) {
        $map = [
            'uid'         => $uid,
            'type'        => $type,
            'expire_time' => ['gt', time()],
        ];

        return $this->where($map)->field('id')->select(true)->toArray('id');
    }

    /**
     * 吊销一批Token
     *
     * @param array|string $tokenIds
     *
     * @return bool
     */
    public function unsetTokens($tokenIds = []) {
        $map = [
            'id' => ['in', $tokenIds],
        ];
        if (is_string($tokenIds)) {
            $map = [
                'token' => $tokenIds,
            ];
        }

        return $this->where($map)->update(['expire_time' => time()]);
    }

    /**
     * 给一个用户绑定他的token
     *
     * @param     $uid
     * @param int $type
     *
     * @return bool|int
     */
    public function bindToken($uid, $type = 1) {
        $map = [
            'uid'  => $uid,
            'type' => $type,
        ];
        // 获取所有的token
        $tokens = $this->getUidTokens($uid, $type);
        if (count($tokens) > 0) {
            // 吊销其它的token，防止重复使用
            $status = $this->unsetTokens($tokens);
            if (!$status) {
                return false;
            }
        }
        $expire             = $type == 2 ? '+30 day' : '+2 hour';
        $map['expire_time'] = strtotime($expire);
        $map['token']       = $this->generateToken($uid, $type);
        $map['last_time']   = time();
        $this->create($map);
        $status = $this->insert();
        if (!$status) {
            return false;
        }

        return $map['token'];
    }

    /**
     * 获取未过期的token
     *
     * @param     $uid
     * @param int $type
     *
     * @return bool
     */
    public function getActiveToken($uid, $type = 1) {
        $map   = [
            'uid'         => $uid,
            'type'        => $type,
            'expire_time' => ['gt', time()],
        ];
        $token = $this->order('last_time desc')->where($map)->limit(1)->field('token')->find();
        if (!$token) {
            return false;
        }

        return $token['token'];
    }

    /**
     * 更新Token的过期时间
     *
     * @param        $uid
     * @param        $type
     * @param string $token
     *
     * @return bool
     */
    public function updateToken($uid, $type = 1, $token = '') {
        $map    = [
            'uid'   => $uid,
            'type'  => $type,
            'token' => $token,
        ];
        $expire = $type == 2 ? '+30 day' : '+2 hour';

        return $this->where($map)->update(['expire_time' => strtotime($expire)]);
    }
}
